package com.bsoft.gol.editor.controller;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import ctd.util.JSONUtils;
import com.bsoft.gol.editor.editor.base.EditorFormQr;
import com.bsoft.gol.editor.editor.qo.AddEditorFormQrQo;
import com.bsoft.gol.editor.editor.qo.QueryEditorFormQrQo;
import com.bsoft.gol.editor.editor.qo.RemoveEditorFormQrQo;
import hcn.util.BaseResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.atag.dao.model.PageInfo;
import com.bsoft.gol.editor.service.EditorFormQrApi;
import com.bsoft.gol.editor.utils.posterUtil.ExportInfo;
import com.bsoft.gol.editor.utils.posterUtil.MatrixToImageWriter;
import com.bsoft.gol.editor.utils.posterUtil.PosterUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @program: Myproject
 * @description: 表单二维码
 * @author: zangsf
 * @create: 2022-12-17 13:23
 **/
@Controller
@RequestMapping(value = "/api/auth/editorFormQr")
public class EditorFormQrController {
    private static final Logger logger = LoggerFactory.getLogger(EditorFormQrController.class);


    @Autowired
    private EditorFormQrApi editorFormQrApi;
    @Autowired
    private PosterUtil posterUtil;
    @Value("${image_download_url}")
    private String imageDownloadUrl;

    /* *
     * @description :查询表单列表
     * @author      :zangsf
     * @date        :2022-12-17 14:06
     * @param       :[qo]
     * @return      :hcn.util. public BaseResponse <org.atag.dao.model.PageInfo<com.bsoft.gol.editor.editor.base.EditorFormQr>>
     */
    @RequestMapping(value = "/list")
    @ResponseBody
    public BaseResponse<PageInfo<EditorFormQr>> list(@RequestBody QueryEditorFormQrQo qo) {
        return editorFormQrApi.list(qo);
    }

    /* *
     * @description :删除表单
     * @author      :zangsf
     * @date        :2022-12-17 14:07
     * @param       :[qo]
     * @return      :hcn.util. public BaseResponse
     */
    @RequestMapping(value = "/remove")
    @ResponseBody
    public BaseResponse remove(@RequestBody List<String> qo) {
        RemoveEditorFormQrQo qrQo = new RemoveEditorFormQrQo();
        qrQo.setIdList(qo);
        return editorFormQrApi.remove(qrQo);
    }

    /* *
     * @description :更新表单二维码
     * @author      :zangsf
     * @date        :2022-12-17 14:13
     * @param       :[qo]
     * @return      :hcn.util. public BaseResponse
     */
    @RequestMapping(value = "/update")
    @ResponseBody
    public BaseResponse update(@RequestBody EditorFormQr qo) {
        return editorFormQrApi.update(qo);
    }

    /* *
     * @description :添加表单二维码
     * @author      :zangsf
     * @date        :2022-12-17 14:21
     * @param       :[qo]
     * @return      :hcn.util. public BaseResponse
     */
    @RequestMapping(value = "/add")
    @ResponseBody
    public BaseResponse add(@RequestBody List<AddEditorFormQrQo> qos) {
        return editorFormQrApi.add(qos);
    }

    /* *
     * @description :导出表单二维码
     * @author      :zangsf
     * @date        :2022-12-17 14:21
     * @param       :[qo]
     * @return      :hcn.util. public BaseResponse RemoveEditorFormQrQo qos
     */
    @RequestMapping(value = "/export")
    @ResponseBody
    public String export(@RequestBody List<ExportInfo> doctorInfoList, HttpServletRequest req, HttpServletResponse response) throws IOException {
        String basepath="/usr/local/tomcat/webapps/followup/uploadFile";
        logger.info("二维码存放地址path：" + basepath);
        logger.info("下载二维码doctorInfoList：" + JSONUtils.toString(doctorInfoList));
        List<String> paths = new ArrayList<>();
        if (doctorInfoList != null && doctorInfoList.size() > 0) {
            for (ExportInfo info : doctorInfoList) {
                info.setAvatarFileId(imageDownloadUrl + info.getAvatarFileId());
                try {
                    logger.info("二维码存放地址realPath：" + basepath);
                    File file = new File(basepath + File.separator + "picture" + File.separator + info.getLocalDoctorId() + ".png");
                    File bgimgFile= new File(req.getServletContext().getRealPath("/uploadFile") + File.separator + "bgimg.png");
                    if (!file.exists()){
                        if (!file.getParentFile().exists()) {
                            //创建上级目录
                            file.getParentFile().mkdirs();
                        }
                        try {
                            //在上级目录里创建文件
                            file.createNewFile();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (!bgimgFile.exists()){
                        bgimgFile.createNewFile();
                    }
                    generateQRCodeImage(info.getUrl(), 300, 300, file);
                    if (info.getDoctorLevel() == null || (info.getDoctorLevel() != null && "".equals(info.getDoctorLevel()))) {
                        info.setDoctorLevel("医生");
                    }
                    String filepath = posterUtil.drawImg(basepath, file, info.getDoctorName(), info.getDoctorLevel()
                            , info.getLocalDoctorId(), info.getOrgName(),bgimgFile , info);
                    paths.add(filepath);
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.info("下载二维码异常e.getMessage()：" + e.getMessage());
                }
            }
        }

        if (paths.size() != 0) {
            // 创建临时路径,存放压缩文件
            String filename = "qr-" + System.currentTimeMillis() + ".zip";
            String zipFilePath = basepath + File.separator + "zip" + File.separator + filename;
            // 压缩输出流,包装流,将临时文件输出流包装成压缩流,将所有文件输出到这里,打成zip包
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath));
            // 循环调用压缩文件方法,将一个一个需要下载的文件打入压缩文件包
            for (String path : paths) {
                // 该方法在下面定义
                fileToZip(path, zipOut);
            }
            // 压缩完成后,关闭压缩流
            zipOut.close();

            //拼接下载默认名称并转为ISO-8859-1格式
            String fileName = new String((filename).getBytes(), "ISO-8859-1");
            response.setHeader("Content-Disposition", "attchment;filename=" + fileName);

//            //该流不可以手动关闭,手动关闭下载会出问题,下载完成后会自动关闭
//            ServletOutputStream outputStream = response.getOutputStream();
//            FileInputStream inputStream = new FileInputStream(zipFilePath);
            // 如果是SpringBoot框架,在这个路径
            // org.apache.tomcat.util.http.fileupload.IOUtils产品
            // 否则需要自主引入apache的 commons-io依赖
            // copy方法为文件复制,在这里直接实现了下载效果
//            IOUtils.copy(inputStream, outputStream);

            // 关闭输入流
//            inputStream.close();

            //下载完成之后，删掉这个zip包
//            File fileTempZip = new File(zipFilePath);
//            fileTempZip.delete();

            return filename;
        }
        return null;
    }


    public static void fileToZip(String filePath, ZipOutputStream zipOut) throws IOException {
        // 需要压缩的文件
        File file = new File(filePath);
        // 获取文件名称,如果有特殊命名需求,可以将参数列表拓展,传fileName
        String fileName = file.getName();
        FileInputStream fileInput = new FileInputStream(filePath);
        // 缓冲
        byte[] bufferArea = new byte[1024 * 10];
        BufferedInputStream bufferStream = new BufferedInputStream(fileInput, 1024 * 10);
        // 将当前文件作为一个zip实体写入压缩流,fileName代表压缩文件中的文件名称
        zipOut.putNextEntry(new ZipEntry(fileName));
        int length = 0;
        // 最常规IO操作,不必紧张
        while ((length = bufferStream.read(bufferArea, 0, 1024 * 10)) != -1) {
            zipOut.write(bufferArea, 0, length);
        }
        //关闭流
        fileInput.close();
        // 需要注意的是缓冲流必须要关闭流,否则输出无效
        bufferStream.close();
        // 压缩流不必关闭,使用完后再关
    }


    private static void generateQRCodeImage(String text, int width, int height, File file) throws WriterException, IOException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();

        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height);

        MatrixToImageWriter.writeToFile(bitMatrix, "PNG", file);

    }


}
